package com.googlecode.YaccSyntaxTool.grammar;

import java.util.Set;

import com.googlecode.YaccSyntaxTool.export.Exporter;
import com.googlecode.YaccSyntaxTool.export.NotSupportedExportKindException;
import com.googlecode.YaccSyntaxTool.export.ReferenceMap;

public class Rule {
	private final String		nonterminal;
	private final Expression	expression;

	public Rule(String nonterminal, Expression expression) {
		super();
		this.nonterminal = nonterminal;
		this.expression = expression;
	}

	public String getNonterminal() {
		return nonterminal;
	}

	public Expression getExpression() {
		return expression;
	}

	/*
	 * EXPORT
	 */
	public void export(Exporter exporter) throws NotSupportedExportKindException {

		switch (exporter.getKind()) {
		case TXT:
			exporter.appendNonterminal(nonterminal);
			exporter.append(" = ");
			expression.export(exporter);
			exporter.append(" .\n");
			break;
		case HTML:
			if (nonterminal.startsWith("$@")) {
				break;
				/* do nothing, ignore on export */
			}
			exporter.appendNonterminal(nonterminal);
			exporter.appendNonterminalReferences(nonterminal);
			exporter.appendLineBreak();
			// export expression
			expression.export(exporter);
			exporter.appendLineSeparator();
			break;
		case HTMLCOMPACT:
			if (nonterminal.startsWith("$@")) {
				break;
				/* do nothing, ignore on export */
			}
			exporter.append("<table>");
			exporter.append("<tr>");
			exporter.append("<td nowrap valign=top>");
			exporter.appendNonterminal(nonterminal);
			exporter.append(" ::=");
			exporter.append("</td>");
			// export expression
			exporter.append("<td>");
			expression.export(exporter);
			exporter.append("</td>");
			exporter.append("</tr>");
			exporter.append("</table>");
			break;
		default:
			throw new NotSupportedExportKindException(exporter.getKind());
		}
	}

	/*
	 * REFERENCES
	 */
	public void fillReferenceMap(ReferenceMap refMap, FactorType type) {
		expression.fillReferenceMap(refMap,type,nonterminal);
	}

	/*
	 * EXTRACT
	 */
	public Set<String> getUsedNonterminals() {
		return expression.getUsedNonterminals();
	}
}
